#      .-.     .-.     .-.     .-.     .-.     .-.
# `._.'   `._.'   `._.'   `._.'   `._.'   `._.'   `
#
# github.com/rafi tmux config
#

# Behavior
#-------------------------------------------------

set -g default-shell "${SHELL}"
# set -g default-terminal "${TERM}"
set -g default-terminal "xterm-kitty"
# set -g default-terminal "alacritty"
# set -g default-terminal "screen-256color"
# set -g default-terminal "tmux18-256color"
# set -g default-terminal "xterm-256color"

# Reattach each new window to the user bootstrap namespace
# if-shell \
#   'test "$(uname -s)" = Darwin' \
#   'set -g default-command "exec reattach-to-user-namespace -l $SHELL"'

set -g set-titles on
set -g set-titles-string '#T #S:#I.#P #W'

setw -g automatic-rename on
setw -g xterm-keys on

# Always honor extended keys, fixes Alacritty mods.
set-option -s -a extended-keys always

# Enable cursor shape modification in vim without Ptmux wrap
# See https://github.com/neovim/neovim/wiki/FAQ
set-option -s -a terminal-overrides ',*:Ss=\E[%p1%d q:Se=\E[2 q'

# Enable 24-bit color support (check if this works via `tmux info | grep Tc`)
set-option -s -a terminal-overrides ",*:Tc"

# Add Undercurl (test it with `printf '\e[4:3mUndercurl\n\e[0m'`)
set-option -s -a terminal-overrides ',*:Smulx=\E[4::%p1%dm'

# Add colored undercurl (test it with `printf '\e[4:3;58:2:255:100:0mUndercurl\n\e[0m'`)
set-option -s -a terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m'

# scrollback buffer size increase
set -g history-limit 20000

# Limit buffer stack
set -g buffer-limit 20

# Address vim mode switching delay (http://superuser.com/a/252717/65504)
set -s escape-time 0

# tmux messages are displayed for 2 seconds
set -g display-time 2000

# Allow the arrow key to be used immediately after changing windows, default is 500
set -g repeat-time 300

# focus events enabled for terminals that support them
set -g focus-events on

# Rather than constraining window size to the maximum size of any client
# connected to the *session*, constrain window size to the maximum size of any
# client connected to *that window*. Much more reasonable.
setw -g aggressive-resize on

# Start windows and panes from 1
set -g base-index 1
setw -g pane-base-index 1

# Visual notifications
set -g visual-bell off
set -g visual-activity off
# See https://github.com/fcsonline/tmux-thumbs/issues/88
set -g visual-silence on

# Window Monitoring
setw -g monitor-activity on
setw -g monitor-silence 0

# Key bindings
#-------------------------------------------------

# Act like GNU screen, use C-a instead of C-b
unbind-key C-b
set -g prefix C-a

# In nested tmux clients, send prefix with C-a C-a, or C-a a
bind-key C-a send-prefix
bind-key a send-prefix

# Open new window from current path
bind-key c new-window -c "#{pane_current_path}"

# Create new session
bind-key N new-session

# Link window from different session/window
bind L command-prompt -p "Link window from (session:window):" "link-window -s %% -a"

# Merge session with another one (e.g. move all windows)
# If you use adhoc 1-window sessions, and you want to preserve session upon exit
# but don't want to create a lot of small unnamed 1-window sessions around
# move all windows from current session to main named one (dev, work, etc)
bind C-u command-prompt -p "Session to merge with:" \
  "run-shell 'yes | head -n #{session_windows} | xargs -I {} -n 1 tmux movew -t %%'"

# Hide status bar on demand
bind C-s if -F '#{s/off//:status}' 'set status off' 'set status on'

# Window monitoring for activity and silence
bind m setw monitor-activity \; display-message 'Monitor window activity [#{?monitor-activity,ON,OFF}]'
bind M if -F '#{monitor-silence}' \
  'setw monitor-silence 0 ; display-message "Monitor window silence [OFF]"' \
  'command-prompt -p "Monitor silence: interval (s)" "setw monitor-silence %%"'

# Kill a session
bind-key D choose-tree -sf "kill-session -t '%%'"

# Use v and g for splitting from current path
unbind-key %
unbind-key '"'
bind-key g split-window -h -c "#{pane_current_path}"
bind-key v split-window -v -c "#{pane_current_path}"
bind-key | split-window -h -c "#{pane_current_path}"
bind-key - split-window -v -c "#{pane_current_path}"

# Session navigation
bind-key n switch-client -n
bind-key p switch-client -p

# Window navigation with Meta+h/l/left/right
bind-key -n M-h previous-window
bind-key -n M-l next-window
bind-key -n M-Left previous-window
bind-key -n M-Right next-window

# Window Re-order
bind-key -n M-< swap-window -d -t -1
bind-key -n M-> swap-window -d -t +1

# Pane navigation
bind-key h select-pane -L
bind-key j select-pane -D
bind-key k select-pane -U
bind-key l select-pane -R

# Smart pane switching with awareness of vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|l?n?vim?x?|fzf)(diff)?$'"
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h'  'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j'  'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k'  'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l'  'select-pane -R'
tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'
if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'select-pane -l'"

bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
bind-key -T copy-mode-vi 'C-\' select-pane -l

bind-key C-h send-keys 'C-h'
bind-key C-j send-keys 'C-j'
bind-key C-k send-keys 'C-k'
# Bring back clear screen under tmux prefix
bind-key C-l send-keys 'C-l'

# Toggle synchronized input to all panes in current window
bind-key S setw synchronize-panes

# Quick layout shortcuts
bind-key b setw main-pane-width 90\; select-layout main-vertical
bind-key B setw main-pane-height 30\; select-layout main-horizontal

# Use a tick for renaming the window prompt
bind-key r command-prompt -I '#W' -p '(rename window)' "rename-window '%%'"
bind-key R command-prompt -I '#S' -p '(rename session)' "rename-session '%%'"

# Open a man page in new vertical pane
bind-key / command-prompt -p 'Man>' "split-window -d -v 'exec man %%'"

# Open ncmpcpp in new pane
# bind-key C-m split-window -v "exec ~/.local/bin/ncmpcpp"

# Use Facebook PathPicker to select paths from buffer interactively
# bind-key f capture-pane \; \
# 	save-buffer /tmp/tmux-buffer \; \
# 	new-window -c "#{pane_current_path}" "sh -c 'cat /tmp/tmux-buffer | fpp -c \"vim -O\" && rm /tmp/tmux-buffer'"

# Use urlview for displaying all links from buffer
bind-key u capture-pane -J \; save-buffer /tmp/tmux-buffer \; split-window -l 10 "urlview '/tmp/tmux-buffer' && rm /tmp/tmux-buffer"

# Quick view of processes
bind-key P split-window -h 'exec htop'

# Help screen: rebind list-keys window into a new pane
bind-key ? split-window -h 'exec tmux list-keys | less'

# Open new window from current path
bind-key i split-window -c "#{pane_current_path}" -h 'lf'

# Force a reload of the config file
bind-key C-r source-file $XDG_CONFIG_HOME/tmux/tmux.conf \; display "Config reloaded"

bind-key * list-clients

# Search for previous error
bind-key e copy-mode \; send-keys "?error" C-m

# Disable Ctrl+Arrows to maintain word jump
unbind-key -n C-Left
unbind-key -n C-Right
unbind-key -n C-Up
unbind-key -n C-Down

# Control
#-------------------------------------------------

# bind vi key-mapping
set -g status-keys vi

# vi-style controls for copy mode
setw -g mode-keys vi

# Allows scrolling and selecting in copy-mode
set -g -q mouse on

# enable OSC 52 clipboard
# https://medium.freecodecamp.org/tmux-in-practice-integration-with-system-clipboard-bcd72c62ff7b
set -g set-clipboard on

# use bracketed paste, if the running application (vim/emacs/weechat) has
# sent the terminal code to enable it.
bind-key ] paste-buffer -p

# Trigger copy mode by Cmd-Up
# bind -n M-Up copy-mode

# Setup copy-mode vi bindings
# $ tmux -f /dev/null list-keys -T copy-mode-vi
unbind -Tcopy-mode-vi Enter
bind-key Escape copy-mode
bind-key -Tcopy-mode-vi v send -X begin-selection
bind-key -Tcopy-mode-vi V send -X select-line
bind-key -Tcopy-mode-vi C-v send -X rectangle-toggle
bind-key -Tcopy-mode-vi Escape send -X clear-selection

# Yank
# bind -T copy-mode-vi D send-keys -X copy-end-of-line
if-shell 'test "$(uname -s)" = Darwin' {
  %hidden yank="pbcopy"
  bind -Tcopy-mode-vi y send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi Y send -X begin-selection \; send -X end-of-line \; send -X cursor-left \; send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi DoubleClick1Pane select-pane \; send-keys -X select-word \; run-shell -d 0.3 \; send-keys -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi TripleClick1Pane select-pane \; send-keys -X select-line \; run-shell -d 0.3 \; send-keys -X copy-pipe-and-cancel "$yank"
}
if-shell 'which xclip' {
  %hidden yank="xclip -i -selection clipboard"
  bind -Tcopy-mode-vi y send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi Y send -X begin-selection \; send -X end-of-line \; send -X cursor-left \; send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi DoubleClick1Pane select-pane \; send-keys -X select-word \; run-shell -d 0.3 \; send-keys -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi TripleClick1Pane select-pane \; send-keys -X select-line \; run-shell -d 0.3 \; send-keys -X copy-pipe-and-cancel "$yank"
}
if-shell '[ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]' {
  %hidden yank="~/.config/tmux/scripts/yank.sh"
  bind -Tcopy-mode-vi y send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi Y send -X begin-selection \; send -X end-of-line \; send -X cursor-left \; send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi MouseDragEnd1Pane send -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi DoubleClick1Pane select-pane \; send-keys -X select-word \; run-shell -d 0.3 \; send-keys -X copy-pipe-and-cancel "$yank"
  bind -Tcopy-mode-vi TripleClick1Pane select-pane \; send-keys -X select-line \; run-shell -d 0.3 \; send-keys -X copy-pipe-and-cancel "$yank"
}

# Rotate key-bindings to inner/remote tmux session
# See https://github.com/tmux/tmux/issues/237
unbind-key C-o # rotate-window
bind-key C-o  \
  set prefix None \;\
  set key-table off \;\
  set window-status-current-style "bg=colour254" \;\
  if -F '#{pane_in_mode}' 'send-keys -X cancel' \;\
  refresh-client -S \;\

bind-key -T off C-o \
  set -u prefix \;\
  set -u key-table \;\
  set -u window-status-current-style \;\
  refresh-client -S

# bind-key a set-window-option synchronize-panes\; display-message "synchronize-panes is now #{?pane_synchronized,on,off}"

# Look 'n Feel
# ---
set -g status on
set -g status-position top
set -g status-interval 3

source-file $XDG_CONFIG_HOME/tmux/styles/rafi.tmux

# Plugins
# ---
set -g @extrakto_key 'tab'
set -g @extrakto_split_size '12'
run-shell $XDG_CONFIG_HOME/tmux/plugins/extrakto/extrakto.tmux

# set -g @scroll-without-changing-pane 'on'
# set -g @scroll-speed-num-lines-per-scroll '1'
# run-shell $XDG_CONFIG_HOME/tmux/plugins/better-mouse/scroll_copy_mode.tmux

unbind-key f
set -g @thumbs-key f
set -g @thumbs-command 'echo -n {} | pbcopy'
run-shell $XDG_CONFIG_HOME/tmux/plugins/thumbs/tmux-thumbs.tmux

# set -g @fingers-key f
# set -g @fingers-ctrl-action ':open:'
# set -g @fingers-shift-action ':paste:'
# set -g @fingers-hint-position 'right'
# set -g @fingers-hint-format '#[fg=yellow,bold]%s'
# set -g @fingers-highlight-format '#[fg=blue,bold,dim]%s'
# set -g @fingers-selected-hint-format '#[fg=green,bold]%s'
# set -g @fingers-selected-highlight-format '#[fg=red,bold]%s'
# run-shell $XDG_CONFIG_HOME/tmux/plugins/fingers/tmux-fingers.tmux

set -g @pass-key b
run-shell $XDG_CONFIG_HOME/tmux/plugins/pass/plugin.tmux

#  vim: set ft=tmux ts=2 sw=2 tw=80 noet :
